package controllers

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
	common "jihe.common"
	"jihe.common/protos/admin_auth_server"
	admin_auth_server_proto "jihe.common/protos/admin_auth_server/proto"
	"jihe.common/protos/user_server"
	"jihe.common/protos/user_server/proto"
	"jihe.common/protos/wx_server"
	wx_server_proto "jihe.common/protos/wx_server/proto"
	"jihe.common/resp"
	"strings"
	"time"
)

type UserController struct {
	Redis common.Redis
}

func (s *UserController) UpdateBodyData(c *gin.Context) {
	req := proto.UserDUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Id == "" || len(req.BodyData) == 0 {
		resp.RespParamErr(c)
		return
	}
	_, err = user_server.UpdateUserBodyData(c, &req)
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c)
}

func (s *UserController) UpdateUserSex(c *gin.Context) {
	req := proto.UserDUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Id == "" || req.Sex == 0 {
		resp.RespParamErr(c)
		return
	}
	_, err = user_server.UpdateUserSex(c, &req)
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c)
}

func (s *UserController) UpdateUserPhotos(c *gin.Context) {
	req := proto.UserDUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Id == "" || req.Photos == nil {
		resp.RespParamErr(c)
		return
	}
	_, err = user_server.UpdateUserPhotos(c, &req)
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c)
}

func (s *UserController) GetCuserList(c *gin.Context) {
	req := proto.UserListReq{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize > 100 {
		resp.RespParamErr(c)
		return
	}
	userList, err := user_server.GetUserCList(c, &req)
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c, userList)
}

func (s *UserController) UpdateCuser(c *gin.Context) {
	req := proto.UserCUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Phone == "" {
		resp.RespParamErr(c)
		return
	}
	userList, err := user_server.UserCUserUpdate(c, &req)
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c, userList)
}

func (s *UserController) GetDuserList(c *gin.Context) {
	req := proto.UserListReq{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize > 100 {
		resp.RespParamErr(c)
		return
	}
	userList, err := user_server.UserDUserList(c, &req)
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	reqUserGetUserByIds := &proto.UserGetUserByIdsReq{}
	for _, v := range userList.List {
		reqUserGetUserByIds.Uids = append(reqUserGetUserByIds.Uids, v.Id)
	}
	if len(reqUserGetUserByIds.Uids) == 0 {
		resp.RespOk(c)
		return
	}
	var g errgroup.Group
	g.Go(func() error {
		users, err := user_server.UserGetUserByIds(c, reqUserGetUserByIds)
		if err != nil {
			return err
		}
		userList.Users = users.List
		return nil
	})
	g.Go(func() error {
		userAudit, err := user_server.UserGetAuditByUids(c, &proto.UserGetAuditByUidsReq{
			Uids: strings.Join(reqUserGetUserByIds.Uids, ","),
		})
		if err != nil {
			return err
		}
		userList.Audits = userAudit.List
		return nil
	})
	err = g.Wait()
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c, userList)
}

func (s *UserController) GetUserAuditByUids(c *gin.Context) {
	uids := c.Query("uids")
	ret, err := user_server.UserGetAuditByUids(c, &proto.UserGetAuditByUidsReq{
		Uids: uids,
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c, ret.List)
}

func (s *UserController) DoUserAuditAction(c *gin.Context) {
	action := c.Query("action")
	if action != "agree" && action != "refused" {
		resp.RespParamErr(c)
		return
	}
	uid := c.Query("uid")
	if uid == "" {
		resp.RespParamErr(c)
		return
	}
	phrase2, thing9 := "通过", "恭喜你成为芰荷塘一员"
	if action == "agree" {
		_, err := user_server.UserAuditStatus(c, &proto.UserDUserAudit{
			Uid:    uid,
			Status: 2,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
	} else {
		_, err := user_server.UserAuditStatus(c, &proto.UserDUserAudit{
			Uid:    uid,
			Status: 3,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
		phrase2 = "未通过"
		thing9 = "有什么问题请在个人中心联系客服人员"
	}
	userInfo, err := user_server.UserGetByUid(c, &proto.UserDUser{
		Id: uid,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	adminUser, err := admin_auth_server.AdminAuthGetUserByIds(c, &admin_auth_server_proto.AdminAuthGetUserByIdsReq{
		Uids: getUid(c),
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	if len(adminUser.AdminAuthUserList) == 0 {
		resp.RespInternalErr(c)
		return
	}
	miniprogramState := "formal"
	if common.Configer.Runmode == "test" {
		miniprogramState = "trial"
	}
	var wxSendTemplateReq = fmt.Sprintf(`{
	    "touser": "%s",
	    "template_id": "oboX2V7mZxSw8C1OIybXovcWgpLMUnbcZ6Hu8iPj-cU",
	    "page": "pages/index/index",
	    "miniprogram_state":"%s",
	    "lang":"zh_CN",
	    "data": {
	        "phrase2": {
	            "value": "%s"
	        },
	        "thing9": {
	            "value": "%s"
	        },
	        "thing7": {
	            "value": "%s"
	        } ,
	        "time3": {
	            "value": "%s"
	        }
	    }
	}`, userInfo.Openid, miniprogramState, phrase2, thing9, adminUser.AdminAuthUserList[0].Name, time.Now().Format("2006-01-02 15:04:05"))
	_, err = wx_server.WxSendTemplate(c, &wx_server_proto.WxSendTemplateReq{
		Data: wxSendTemplateReq,
	})
	if err != nil {
		resp.RespOk(c, err.Error()+wxSendTemplateReq)
		return
	}
	resp.RespOk(c)
	return
}

func (s *UserController) DisabledUser(c *gin.Context) {
	action := c.Query("action")
	if action != "disable" && action != "enable" {
		resp.RespParamErr(c)
		return
	}
	uid := c.Query("uid")
	if uid == "" {
		resp.RespParamErr(c)
		return
	}
	if action == "disable" {
		_, err := user_server.UserUpdateStatus(c, &proto.UserDUser{
			Id:     uid,
			Status: 2,
		})
		if err != nil {
			resp.RespInternalErr(c, err.Error())
			return
		}
		s.Redis.Get().Del(s.Redis.GetAuthUserTokenKey(uid))
		resp.RespOk(c)
		return
	}
	_, err := user_server.UserUpdateStatus(c, &proto.UserDUser{
		Id:     uid,
		Status: 1,
	})
	if err != nil {
		resp.RespInternalErr(c, err.Error())
		return
	}
	resp.RespOk(c)
	return
}

func (s *UserController) UpdatePlatformDiscount(c *gin.Context) {
	req := proto.UserUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.PlatformDiscount <= 0 || req.Uid == "" {
		resp.RespParamErr(c)
		return
	}
	_, err = user_server.UserUpdateUserById(c, &req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	resp.RespOk(c)
}
